// ==UserScript==
// @name         驴妈妈导价到阿目云辅助脚本
// @namespace    http://tampermonkey.net/
// @version      2021.06.03
// @description  导价到阿目云，提供获取驴妈妈、要出发、广游商旅价格功能。虽然名字叫驴妈妈脚本，实际上合并了多平台的辅助代码
// @author       ╮(╯▽╰)╭
// @updateURL    https://gitee.com/amutravel/lvmama/raw/master/lmmExportPrice/lmmExportPriceAssitant.user.js
// @downloadURL  https://gitee.com/amutravel/lvmama/raw/master/lmmExportPrice/lmmExportPriceAssitant.user.js
// @match        http://fp.lxfx.xyz:9010/pns2amu4*
// @match        http://localhost:9010/pns2amu4*
// @match        http://localhost:3000/
// @include      http://f.lvmama.com/w/hotelpackage/*?platform=dis
// @include      *://www.op118.cn/newb2b/
// @connect      f.lvmama.com
// @connect      u.yaochufa.com
// @connect      zowoyoo.com
// @connect      erp.himudidi.com
// @run-at       document-end
// @grant        GM_xmlhttpRequest
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        unsafeWindow
// ==/UserScript==
;
if(location.href.includes("http://localhost:9010/pns2amu4") 
  || location.href.includes("http://fp.lxfx.xyz:9010/pns2amu4")
  || location.href == "http://localhost:3000/"
){
  unsafeWindow.GM_xmlhttpRequest = GM_xmlhttpRequest

  function formatDate(date, offset = 0) {
    let t = new Date(new Date(date).getTime() + 86400000 * offset);
    return `${t.getFullYear()}-${t.getMonth() + 1 > 9 ? t.getMonth() + 1 : '0' + (t.getMonth() + 1)}-${t.getDate() > 9 ? t.getDate() : '0' + t.getDate()}`;
  }
}
try {
//==============  驴妈妈导价辅助工具  START ========
if(location.href == "http://localhost:9010/pns2amu4lmm" 
  || location.href == "http://fp.lxfx.xyz:9010/pns2amu4lmm"
  || location.href == "http://localhost:3000/"
){
  !GM_xmlhttpRequest && (unsafeWindow.GM_xmlhttpRequest = GM_xmlhttpRequest)

  // === LMM START ===
  // 驴妈妈账号ID
  const LMMUSERID = 9605;

  const LMM = {
    handleResponse(res){
      if(res.response==undefined && ( res.responseText==undefined || res.responseText.match(/<!DOCTYPE html>/) )){
        let isToLmmLogin = window.confirm("这位同学，还没有登录驴妈妈吧？\n或者看看套餐是否下线了？\n都不是的话就联系工具维护人吧...\n\n 现在是否去登录驴妈妈试试？");
        if(isToLmmLogin){
          window.open(res.finalUrl, '_blank');
        }
        return {}
      }else{
        return res.response
      }
    },
    // GM_xmlhttpRequest GET 方法
    gmGet(data) {
      return new Promise(resolve => {
        GM_xmlhttpRequest({
          url: data.url,
          method: 'GET',
          responseType: 'json',
          headers: {Referer: data.referer},
          onload: res => {resolve(LMM.handleResponse(res))},
          onerror: res => {
            console.log(res);
            resolve({})
          }
        })
      })
    },
    // GM_xmlhttpRequest POST 方法
    gmPost(data) {
      const JSONHEADER = {"Content-Type": "application/json;charset=UTF-8"};
      const FORMDATAHEADER = {"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"};
      return new Promise(resolve => {
        GM_xmlhttpRequest({
          url: data.url,
          method: "POST",
          responseType: 'json',
          headers: data.type =='form' ? FORMDATAHEADER : JSONHEADER,
          data: typeof data.data == 'string' ? data.data : JSON.stringify(data.data),
          onload: (res) => {resolve(LMM.handleResponse(res))},
          onerror: (res) => {
            console.log(res);
            resolve({});
          }
        });
      })
    },
    // userId: 9605,  商家账号ID $('#userId').val()
    // 获取价格
    getPrice: {
      // 国内门票 pid: 门票套餐ID，就是请求数据的 saleUnitId
      // http://f.lvmama.com/scenic/product/scenic_product_detail.html?productId=182322
      // http://f.lvmama.com/scenic/product/scenic_product_detail.html?productId=234887
      scenic({packageId}, userId=LMMUSERID) {
        return new Promise(async (resolve) => {
          let postData = {
            url: "http://f.lvmama.com/scenic/timeprice/query",
            type: 'json',
            data: {
              packType: "UN_PACK",
              raiseRule: null,
              saleUnitId: packageId,
              startDate: formatDate(new Date()),
              userId: userId
            }
          };
          let res = await LMM.gmPost(postData);
          if(res.success && res.status=="SUCCESS"){
            resolve(res.timePriceVoList)
          }else{
            console.log('LmmB2B.getPrice.scenic Error:',res);
            resolve([])
          }
        });
      },
      // 酒店 rid: 房型ID， 就是请求数据的 goodsId
      // http://f.lvmama.com/hotel/preview.do/997599?specialSupply=2&startDateStr=2020-01-10&endDateStr=2020-01-11
      hotel({packageId}, userId=LMMUSERID) {
        let postData = {
          url: "http://f.lvmama.com/hotel/findGoodsAddTimePriceList",
          type: 'form',
          data: `goodsId=${packageId}&userId=${userId}`
        };
        return new Promise(async(resolve) => {
          let res = await LMM.gmPost(postData);
          if(res instanceof Array){
            resolve(res)
          }else{
            console.log('LmmB2B.getPrice.hotel Error:',res);
            resolve([])
          }
        });
      },
      // [周边自由行] pid 套餐ID， 就是请求数据的 sellPackageId
      // http://f.lvmama.com/route/product/preview.do/930159
      // http://f.lvmama.com/route/product/preview.do/930139?visitSource=LOCALTOUR
      route({packageId}, userId=LMMUSERID, startDate = '') {
        let checkIn = startDate ? startDate : formatDate(new Date);
        let postData = {
          url: "http://f.lvmama.com/route/product/findProductTimePriceList",
          type: 'form',
          data: `specDate=${checkIn}&userId=${userId}&sellPackageId=${packageId}`
        }
        return new Promise(async (resolve)=>{
          let res = await LMM.gmPost(postData);
          if(res instanceof Array){
            resolve(res)
          }else{
            console.log('LmmB2B.getPrice.route Error:',res);
            resolve([])
          }
        })
      },
      // [酒店套餐] platform=dis不可缺少，表示分销,有数据签名，不过目前并不需要加。我也还没有找到生成方法
      // http://f.lvmama.com/w/hotelpackage/100116069?platform=dis
      hotelpackage({productId,packageId}) {
        let getData = {
          referer: `http://f.lvmama.com/w/hotelpackage/${productId}?platform=dis`,
          url: `http://f.lvmama.com/tims-web/w/product/queryProductPriceCanlander?productId=${productId}&platform=dis&productPackageId=${packageId}`
        };
        return new Promise(async (resolve)=>{
          let res  = await LMM.gmGet(getData);
          if(res.hasOwnProperty('data') && !res.hasError){
            resolve(res.data.dayPrices)
          }else{
            console.log('LmmB2B.getPrice.hotelpackage Error:',res);
            resolve({})
          }
        })
      },
      // [酒店套餐] platform=dis不可缺少，表示分销， 没有数据签名
      // http://f.lvmama.com/w/vacation/100118457?platform=dis
      vacation({packageId}) {
        let getData = {
          referer: `http://f.lvmama.com/w/vacation/${packageId}?platform=dis`,
          url: `http://f.lvmama.com/w/product/querySchedule?productId=${packageId}&platform=dis`,
        };
        return new Promise(async resolve=>{
          let res = await LMM.gmGet(getData);
          if(res.hasOwnProperty('data') && !res.hasError){
            resolve(res.data.datePrices)
          }else{
            console.log('LmmB2B.getPrice.vocation Error:',res);
            resolve({})
          }
        })
      },
      // [当地游] 有数据签名
      // http://f.lvmama.com/w/localtour/100118803?platform=dis
      localtour({packageId, packageCode}) {
        let getData = {
          referer: `http://f.lvmama.com/w/hotelpackage/${packageId}?platform=dis`,
          url: `http://f.lvmama.com/tims-web/w/product/queryProductPriceCanlander?productId=${packageId}&platform=dis&productPackageCode=${packageCode}`
        };
        return new Promise(async resolve=>{
          let res = LMM.gmGet(getData);
          if(res.hasOwnProperty('data') && !res.hasError){
            resolve(res.data.dayPrices);
          }else{
            console.log('LmmB2B.getPrice.localtour Error:',res);
            resolve({})
          }
        })
      },
      // [跟团游] 没有数据签名
      // http://f.lvmama.com/w/tour/100111912?platform=dis
      tour({packageId}) {
        let getData = {
          referer: `http://f.lvmama.com/w/tour/${packageId}?platform=dis`,
          url: `http://f.lvmama.com/w/product/querySchedule?productId=${packageId}&platform=dis`
        };
        return new Promise(async resolve=>{
          let res = await LMM.gmGet(getData);
            if(res.hasOwnProperty('data') && !res.hasError){
              resolve(res.data.datePrices)
            }else{
              console.log('LmmB2B.getPrice.tour Error:',res);
              resolve({})
            }
        })
      },
    },

    // 整理价格，返回同样的格式
    formatPrice: {
      scenic(priceArray) {
        return new Promise((resolve) => {
          let tmp = {};
          for (let item of priceArray) {
            try {
              tmp[item.specDateText] = {
                p: item.tradePriceYuan,
                // lmm库存: -1 充足
                s: item.dayStock
              }
            } catch (error) { console.log('lmmB2B.formatPrice.scenic Error:', error) }
          }
          resolve(tmp)
        });
      },
      hotel(priceArray) {
        return new Promise((resolve, reject) => {
          let tmp = {};
          for (let item of priceArray) {
            try {
              tmp[item.specDateString] = {
                // p: item.auditPrice,
                p: item.tntPrice/100,
                s: item.totalStock
                  ? (item.remainningStock ? -1 : 0)  // 有保留房，就看库存数量
                  : (item.stockStatus == '满房' ? 0 : -1)
                // s: item.hasNotReservedRoom == "Y"
                //   ? (item.stock ? -1 : 0)  // 有保留房，就看库存数量
                //   : (item.stockStatus == '满房' ? 0 : -1)
              }
            } catch (error) { console.log('lmmB2B.formatPrice.hotel Error:', error) }
          }
          resolve(tmp)
        });
      },
      route(priceArray) {
        return new Promise((resolve) => {
          let tmp = {};
          for (let item of priceArray) {
            tmp[item.specDateStr] = {
              p: item.distPrice / 100,
              // 驴妈妈系统： -1 二次确认/正常？ ，这里还需要完善种类
              s: item.stock
            }
          }
          resolve(tmp);
        });
      },
      hotelpackage(priceJson) {
        return new Promise(resolve => {
          let tmp = {};
          for (let d of Object.keys(priceJson)) {
            try {
              tmp[d] = {
                p: parseFloat(priceJson[d].adultPrice),
                // 这里库存是乱设的，加上有数据的日期都是有库存的，可能与 isOverSale 或者 status 有关
                s: -1
              }
            } catch (error) { }
          }
          resolve(tmp)
        })
      },
      vocation(priceJson) {
        return new Promise(resolve => {
          let tmp = {};
          for (let d of Object.keys(priceJson)) {
            try {
              tmp[d] = {
                p: parseFloat(priceJson[d].packageDatePriceDTOS[0].dayPriceDTO.adultPrice),
                // 这里库存是乱设的，加上有数据的日期都是有库存的，可能与 isOverSale 或者 status 有关
                s: -1
              }
            } catch (error) { }
          }
          resolve(tmp)
        })
      },
      localtour(priceJson) {
        return this.hotelpackage(priceJson)
      },
      tour(priceJson) {
        return this.vocation(priceJson)
      }
    }

  }

  unsafeWindow.LMM = LMM
  // === LMM END ===
}else if(location.origin=="http://f.lvmama.com" && location.href.includes("hotelpackage")){
  // hotelpackage 类型的页面
  // http://f.lvmama.com/w/hotelpackage/100116322?platform=dis
  window.showPackageId = ()=>{
    document.querySelectorAll("span[data-template]").forEach(elem=>{
      elem.innerHTML = elem.textContent +'<br>'+ elem.dataset.template.match(/\d+/g)[0];
    })
  };
  window.lmmTimer = setInterval(() => {
    if(document.querySelectorAll("span[data-template]").length){
      clearInterval(window.lmmTimer);
      showPackageId();
    }
  }, 1000);
  
  setTimeout(() => {
    clearInterval(window.lmmTimer);
  }, 10000);

  document.body.addEventListener('dblclick', evt=>{
    if(evt.target.tagName == "TH" && evt.target.textContent.includes("退改规则")){
      showPackageId();
    }
  })
}

//==============  驴妈妈导价辅助工具  END ========
} catch (error) {
  console.warn("[☢ 驴妈妈导价辅助工具 执行出现错误：]", error)
}
try {
//==============  要出发导价辅助工具  START ========
if(location.href == "http://localhost:9010/pns2amu4ycf" 
  || location.href == "http://fp.lxfx.xyz:9010/pns2amu4ycf"
  || location.href == "http://localhost:3000/"
){
  // === YCF START ===
  !GM_xmlhttpRequest && (unsafeWindow.GM_xmlhttpRequest = GM_xmlhttpRequest)

  const YCF = {
    handleResponse(res){
      try {
        if(res.response){
          return res.response
        }else if(res.response == undefined){
          let isToLogin = window.confirm("还没有登录要出发系统吧？\n或者看看套餐是否下线了？\n都不是的话就联系工具维护人吧...\n\n 要去登录要出发系统试试吗？");
          if(isToLogin){
            window.open('http://u.yaochufa.com/ycfad2014/public/login', '_blank');
          }
        }
      } catch (error) {
        console.log('☢ 要出发导价辅助工具 handleResponse Error:', error, res)
        return {}
      }
    },
    // GM_xmlhttpRequest GET 方法
    gmGet(data) {
      return new Promise(resolve => {
        GM_xmlhttpRequest({
          url: data.url,
          method: 'GET',
          responseType: 'json',
          headers: {
            'Accept': 'application/json, text/plain, */*',
            'DNT': '1',
            'Referer': data.referer,
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
          },
          onload: res => {resolve(YCF.handleResponse(res))},
          onerror: res => {resolve(YCF.handleResponse(res))}
        })
      })
    },
    // 获取价格
    getPrice: {
      // packageId   productId   channelLinkId  startDate  endDate
      // http://u.yaochufa.com/sipapi/product/getPackagePriceCalendar?packageId=1898937&productId=4680&channelLinkId=147843&startDate=2020-12-17&endDate=2021-03-17
      ticket({productId, packageId, channelLinkId, startDate, endDate}) {
        return new Promise(async (resolve) => {
          let start = startDate || formatDate(new Date), end = endDate || formatDate(new Date, 90);
          let getData = {
            url: `http://u.yaochufa.com/sipapi/product/getPackagePriceCalendar?packageId=${packageId}&productId=${productId}&channelLinkId=${channelLinkId}&startDate=${start}&endDate=${end}`,
            referer: `http://u.yaochufa.com/ycfad2014/purchase/book?productId=${productId}&packageId=${packageId}&channelLinkId=${channelLinkId}&isPreSale=0&startTime=${start}&source=1`
          };
          let res = await YCF.gmGet(getData);
          if(res.hasOwnProperty('success') && res.success){
            resolve(res.data)
          }else{
            console.log('[☢ 要出发导价辅助工具 getPrice.ticket Error]:',res);
            resolve({})
          }
        });
      },
    },

    // 整理价格，返回同样的格式
    formatPrice: {
      ticket(priceJson) {
        return new Promise((resolve) => {
          let tmp = {};
          for (let key of Object.keys(priceJson)) {
            try {
              tmp[key] = {
                p: priceJson[key] || '',
                // ycf库存: null无库存，非空就是有房 充足
                s: priceJson[key] ? 500 : 0
              }
            } catch (error) { console.log('[YcfB2B.formatPrice.ticket Error]:', error) }
          }
          resolve(tmp)
        });
      },
    }

  }

  unsafeWindow.YCF = YCF
  // === YCF END ===
}
//==============  要出发导价辅助工具  END ========
} catch (error) {
  console.warn("[☢ 要出发导价辅助工具 执行出现错误：]", error)
}
try {
//==============  广游商旅导价辅助工具  START ========
if(location.href == "http://localhost:9010/pns2amu4gysl" 
  || location.href == "http://fp.lxfx.xyz:9010/pns2amu4gysl"
  || location.href == "http://localhost:3000/"
){
  !GM_xmlhttpRequest && (unsafeWindow.GM_xmlhttpRequest = GM_xmlhttpRequest)
  unsafeWindow.GM_setValue = GM_setValue

  // === GYSL START ===
  const GYSL = {
    handleResponse(res){
      if (res.status == 200) {
        return res.response
      } else if(res.status == 401){
        let isToLogin = window.confirm("这位同学，还没有登录广游商旅系统吧？\n也可能是登陆了不过工具身份认证信息过期。\n或者看看套餐是否下线了？\n都不是的话就联系工具维护人吧...\n\n 现在是否去登录广游商旅系统试试？");
        if(isToLogin){
          window.open('http://www.op118.cn/', '_blank');
        }
        alert('还没有登录广游商旅系统')
        return{}
      }else{
        console.log('☢ 广游导价辅助脚本→handleResponse Error:', res.response)
        return {}
      }
    },
    // GM_xmlhttpRequest GET 方法
    gmGet(data) {
      return new Promise(resolve => {
        GM_xmlhttpRequest({
          url: data.url,
          method: 'GET',
          responseType: 'json',
          headers: {
            'Accept': 'application/json, text/plain, */*',
            'channel': '0',
            'DNT': '1',
            'Origin': 'http://www.op118.cn',
            'Referer': 'http://www.op118.cn/newb2b/',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36',
            // 'X-Authorization': localStorage.getItem('header')
            // 'authtoken': localStorage.getItem('pcHeader')
            'authtoken': GM_getValue('GYSL', {authtoken:''}).authtoken
          },
          onload: res => { resolve(GYSL.handleResponse(res)) },
          onerror: res => { resolve({}) }
        })
      })
    },
    // 获取价格
    getPrice: {
      ticket({packageId, startDate, endDate}) {
        return new Promise(async (resolve) => {
          let start = startDate || formatDate(new Date), end = endDate || formatDate(new Date, 90);
          let getData = {
            // url: `https://b2bapi.zowoyoo.com/api/b2b/ticket/price?infoId=${packageId}&treeId=0&startDate=${start}&endDate=${end}`,
            url: `https://task-api.zowoyoo.com/api/product/common/priceCalendar?infoId=${packageId}&treeId=0&startDate=${start}&endDate=${end}&planId=-99&month=${end.slice(5,7)}&year=${end.slice(0,4)}`,
          };
          let res = await GYSL.gmGet(getData);
          try {
            if(res.state==1 && Array.isArray(res.data)){
              resolve(res.data)
            }else{
              console.log('广游导价辅助脚本→getPrice.ticket Error:',res);
              resolve([])
            }
          } catch (error) {
            console.log('广游导价辅助脚本→getPrice.ticket Error:',res);
            resolve([])
          }
        });
      },
    },

    // 整理价格，返回同样的格式
    formatPrice: {
      ticket(priceArray) {
        return new Promise((resolve) => {
          let tmp = {};
          for (let item of priceArray) {
            try {
              tmp[item.travelDate] = {
                p: item.price,
                // lmm库存: -1 充足
                s: item.num
              }
            } catch (error) { console.log('广游导价辅助脚本→formatPrice.ticket Error:', error) }
          }
          resolve(tmp)
        });
      },
    }

  }

  unsafeWindow.GYSL = GYSL
  // === GYSL END ===
}
else if(location.href.includes("http://www.op118.cn/newb2b/")){
  GM_setValue('GYSL', {authtoken: localStorage.getItem('pcHeader')})
  console.log("[☣ 成功更新广游 GYSL.autotoken 身份信息]")

  // 如果是广游商旅未授权页面( 401 页面)，那就直接重定向，不需要生成后面那一大堆的东西
  // 跳转到具体页面
  if (location.href == 'http://www.op118.cn/newb2b/#/home') {
    let locationHash = GM_getValue('GYSL_LOCATION_HASH', '')
    if (locationHash.length) {
      setTimeout(() => {
        location.hash = locationHash
        GM_setValue('GYSL_LOCATION_HASH', '')
      }, 1500);
    }
    return
  }
}


//==============  广游商旅导价辅助工具  END ========
} catch (error) {
  console.warn("[☢ 广游商旅导价辅助工具 执行出现错误：]", error)
}
